The original way React components held state and lifecycle logic.
Class components extend React.Component, hold state on this.state, update it via this.setState, and define what renders in a render() method. Because class methods aren't automatically bound to the instance in JavaScript, event handlers referenced as this.handleClick historically lost their this unless explicitly bound in the constructor or written as arrow function class properties — a common source of 'cannot read property of undefined' bugs before hooks existed.
Class components aren't purely legacy, though — they're still the only way to implement an error boundary, since there's no hook equivalent for componentDidCatch or getDerivedStateFromError yet. Understanding them also matters for reading and maintaining older codebases, and for grasping what shouldComponentUpdate() and React.PureComponent were solving before React.memo existed for function components.
What you'll walk away knowing